iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
0
自我挑戰組

Kotlin Everyday:新手寫程式踩的坑系列 第 12

Day 12 ─用 Kotlin 做貓咪圖片滑頁 (上) ViewPager

  • 分享至 

  • xImage
  •  

試做一個ImageSlider,具有滑動效果,會跑出一張張貓咪相片,可以往前、往回滑,同時下面有文字顯示目前位置是在第幾張相片。

使用:ImageView、TextView、ViewPager

ViewPager概念和 RecycleView 類似, RecycleView 是把一筆筆資料按照格式塞進一個頁面,ViewPager就像是橫向的塞資料:

兩者同樣是把資料塞進一個框架裡,所以我們同樣會運用到 Adapter 來整合畫面和資料,步驟和 RecycleView相似:

  1. 設定好 layout 畫面之後
  2. 撰寫 Adapter (整合資料和畫面)
  3. 在 MainActivity 把 Adapter 指給 ViewPager

稍微了解流程後,我們要開始來實作 ImageSlider 囉~

步驟一:設定layout
在 layout/activity_main 新增一個 viewPager,viewPager 是一個容器,等下要用來裝圖片的容器,底下拉一個用來顯示圖片位置的文字,TextView設定置中和外型(Display2)

<TextView
    android:gravity="center"
    android:textAppearance="@style/TextAppearance.AppCompat.Display2"/>

接著在 res/layout 拉一個 xml 檔,用來繪製貓咪圖片的長寬,類似在 RecycleView 每筆資料的 itemView,就是作為模板,每張貓咪圖片的顯示都會按照這個範本去做,因為我的圖片有橫幅、也有直向,所以設定 centerCrop 性質:

<ImageView
     android:scaleType="centerCrop"/>  //圖片原尺寸比例擴大、縮小,多餘部分被裁切

這裡我有一個小問題是,為什麼 TextView 不放在圖片範本的 xml 檔,原因是因為 TextView 不會跟著滑頁而移動,真正改變的只是它顯示的文字內容( text ),它本身沒有移動。

步驟二:Adapter 設定
如果不清楚 Adapter 的概念,可以先去看我第8天的練習 Day 8 ─用Kotlin RecycleView做一個ImageList,這裡講解會比較精簡:

在 File/New/Kotlin File 建立一個名為「Adapter」的 class 檔案,這次讓它繼承的是 PagerAdapter,定義context、list的屬性,之後可以直接覆值

class Adapter(val context: Context, val list: List<Int>) : PagerAdapter() {}

而在 PagerAdapter 裡,有四個要被實作的 function,在紅色底線處按 alt+enter 把它們 implement 進來:

class Adapter(val context: Context, val list: List<Int>) : PagerAdapter() {
    override fun instantiateItem(container: ViewGroup, position: Int): Any {
    
    }
    override fun isViewFromObject(view: View, any: Any): Boolean {
    
    }
    override fun getCount(): Int {
    
    }
    override fun destroyItem(container: ViewGroup, position: Int, view: Any) {
    
    }
}

這篇 ImageSlider 練習參考自 小魚的Android Kotlin 實作 Day 9,有興趣的人可以去她的文章補齊語法,概念講解非常清楚,下面我只會簡單筆記一下:

  1. instantiateItem 實例化頁面,主要將xml資源加載成View,把要顯示的圖片list載入View裡頭的imageView,將View裝到container並且回傳
instantiateItem(container: ViewGroup, position: Int): Object
  • container:用來放View的容器,使用方式就是將項目放進container--container.addView()
  • position:實例化 View 頁面位置
  • Object:項目 View 的 Object,這個回傳的 Object 會被 isViewFromObject 拿來做判斷使用

使用Glide

這邊有使用到一種強大的圖片加載器Glide,使用方式很簡單,第一步先去gradle加入以下兩行,點顯示的藍字同步(Sync Now)

dependencies {
    compile 'com.github.bumptech.glide:glide:3.6.1'
    compile 'com.android.support:support-v4:19.1.0'
}

之後可以直接import了,Gradle就短短一行程式碼:Glide.with(fragment).load(url).into(imageView)
使用方式即(with)當前上下文中載入(load)一張圖片到(into)imageView元件

override fun instantiateItem(container: ViewGroup, position: Int): Any {
    val inflater = LayoutInflater.from(context)
    val view = inflater.inflate(R.layout.imageview, container, false)
    
    Glide.with(context).load(list[position]).into(view.imageView)
                              //用Glide加載圖片view
    container.addView(view)   //將 view 加進 container 裡面
    return view
}
  1. isViewFromObject 判斷頁面 View 和 instantiateItem 回傳物件是否一致
isViewFromObject(view: View, any: Any): Boolean
  • view:傳入的他們想判斷的 View
  • object:剛剛 instantiateItem 回傳的 Object
override fun isViewFromObject(view: View, any: Any): Boolean {
    return view == any
}
  1. getCount() 回傳 ViewPager 的項目個數
override fun getCount(): Int {
    return list.size
}
  1. destroyItem(ViewGroup, int, Object) 用來移除不在檢視範圍的View,將View從container中移除---container.removeView()
  • container:將 View 從 container 中移除
  • position:要移除 View 的頁面位置
  • Object:要移除的項目 View 的 Object,為 instantiateItem 回傳的 Object
override fun destroyItem(container: ViewGroup, position: Int, view: Any) {
    container.removeView(view as View)
}

寫完這四個function,就完成PagerAdapter設定,明天我們會將Adapter指給ViewPager,來完成貓咪圖片滑頁~


上一篇
Day 11 ─用Kotlin RecycleView切換佈局 (下) layoutManager、menu item、vector
下一篇
Day 13 ─用Kotlin 做貓咪圖片滑頁 (下) ViewPager、getIdentifie
系列文
Kotlin Everyday:新手寫程式踩的坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言